/*
 * @文件描述: 示波器模块的UI界面
 * @版本: 
 * @作者: 周晨阳
 * @Date: 2021-01-24 15:21:47
 * @说明
 * 采用MVP架构
 * view层的代码只负责显示，除了必要的内部逻辑函数以外，不会处理其他东西
 * 主要的逻辑代码都在model层，view层和model层通过presenter层通信
 */
#ifdef GUI_UCGUI
#include "OscilloscopeUICodes.h"
#include "measureWindowUI.h"
#include "cursorWindow.h"
#include "HomePagePre.h"
#ifndef WIN_SIM
#define USE_GRAM
#endif
#define DEG2RAD (3.1415926f / 180)

#define Y_MIDDEL 240
#define X_MIDDEL 390

#define LEFT_PADDING 24
#define TOP_PADDING 30
#define BOTTOM_PADDING 30
#define RIGHT_PADDING 100

//顶部波形指示窗口
#define TOP_WAVE_WIN_X1 163
#define TOP_WAVE_WIN_Y1 1
#define TOP_WAVE_WIN_X2 621
#define TOP_WAVE_WIN_Y2 28

#define TOP_WAVE_WIN_WIDTH (TOP_WAVE_WIN_X2 - TOP_WAVE_WIN_X1)
#define TOP_WAVE_WIN_HEIGHT (TOP_WAVE_WIN_Y2 - TOP_WAVE_WIN_Y1)

//顶部运行状态指示窗口
#define TOP_RUNNING_STATE_WIN_X1 33
#define TOP_RUNNING_STATE_WIN_Y1 1
#define TOP_RUNNING_STATE_WIN_X2 134
#define TOP_RUNNING_STATE_WIN_Y2 28

#define TOP_RUNNING_STATE_WIN_WIDTH (TOP_RUNNING_STATE_WIN_X2 - TOP_RUNNING_STATE_WIN_X1)
#define TOP_RUNNING_STATE_WIN_HEIGHT (TOP_RUNNING_STATE_WIN_Y2 - TOP_RUNNING_STATE_WIN_Y1)

//顶部触发指示窗口
#define TOP_TRIGGER_WIN_X1 647
#define TOP_TRIGGER_WIN_Y1 1
#define TOP_TRIGGER_WIN_X2 760
#define TOP_TRIGGER_WIN_Y2 28

#define TOP_TRIGGER_WIN_WIDTH (TOP_TRIGGER_WIN_X2 - TOP_TRIGGER_WIN_X1)
#define TOP_TRIGGER_WIN_HEIGHT (TOP_TRIGGER_WIN_Y2 - TOP_TRIGGER_WIN_Y1)

#define WAVE_WIN_BRACKET_PADDING 3

#define LCD_HEIGHT 854
#define LCD_WIDTH 480
//示波器显示区域
#define METER_WINDOW_WIDTH (LCD_HEIGHT - RIGHT_PADDING - LEFT_PADDING)
#define METER_WINDOW_HEIGHT (LCD_WIDTH - TOP_PADDING - BOTTOM_PADDING)
//波形颜色
#define LINE_COLOR 0xeeff41
//示波器外壳颜色
#define BG_COLOR 0x84868a
//示波器窗口背景色
#define METER_BG_COLOR 0x000000
//小提示框背景颜色
#define INFO_WIN_BG_COLOR 0x424242

//水平时基总数
#define HORIZON_SCALE_CNT 10
#define SCALE_LENGHT METER_WINDOW_WIDTH / HORIZON_SCALE_CNT
//垂直时基总数
#define VERTICAL_SCALE_CNT 6
//每一个时基内的像素个数
#define PIXEL_PER_SCALE METER_WINDOW_WIDTH / HORIZON_SCALE_CNT

#define TRIG_TYPE_RISING 0
#define TRIG_TYPE_FALLING 1

//光标类型，x类型
#define CURSOR_TYPE_X 1
//y类型
#define CURSOR_TYPE_Y 2
//触发光标类型
#define CURSOR_TYPE_TRIGGER 3
/*********************************************************************
*
*       Dialog resource
*
* This table conatins the info required to create the dialog.
* It has been created by ucGUIbuilder.
*/

//EventsFunctionList
void OnButton5Clicked(WM_MESSAGE *pMsg);
void OnButton4Clicked(WM_MESSAGE *pMsg);
void OnButton3Clicked(WM_MESSAGE *pMsg);
void OnButton2Clicked(WM_MESSAGE *pMsg);
void OnButton1Clicked(WM_MESSAGE *pMsg);
//EndofEventsFunctionList

/*********************************************************************
*
*       static data
*
**********************************************************************
*/
GUI_AUTODEV AutoDev;
GUI_AUTODEV_INFO AutoDevInfo;
uint8_t useGram;

static GUI_POINT *displayData;
static OscillInfo *ParamList;
static OscillInfo *CursorParamList;

static unsigned int PointSize;
static uint8_t triggerState;
static char H_Scale[15] = "Time: 200us";
static char V_Scale[15] = "CH1: 5V";
static char triggerVoltageString[10] = "0V";
static float triggerVoltage = 0;
static WM_HWIN Hwin;
static uint16_t TriggerCursorPos;
static uint8_t TriggerCursorState;
//当前菜单页数
static uint8_t CurrentMenuPageNum = 0;
//菜单项总数
static uint8_t MenuCnt = 10;
static MenuInfo *menuInfo;
static char *menuStr[5];
static Cursor *Cursors;
//自动绘制对象
GUI_AUTODEV AutoDev;
//测量光标坐标

//测量光标是否显示
static unsigned char cursorState[2] = {0, 0};
//水平箭头的偏移，相对于窗口的中心点,正为向左偏移
static int H_arrowoffset = 0;
//垂直箭头的偏移，相对于窗口的中心点，正为向上偏移
static int V_arrowoffset = 0;

static uint8_t triggerType;

static float WaveRectWidth;
static int WaveRectMidPos;

/******以下为一些图形的坐标参数，参考ps******/
//左边箭头的绘制参数,在正中央的坐标
const static GUI_POINT leftArrow[5] = {{2, 232}, {16, 232}, {25, 240}, {16, 248}, {2, 248}};
//顶上箭头的绘制参数，在正中央的坐标
const static GUI_POINT topArrow[5] = {{384, 31}, {400, 31}, {400, 45}, {392, 54}, {384, 45}};
//触发方式箭头，上升沿
const static GUI_POINT triggerRisingArrow[3] = {{TOP_TRIGGER_WIN_X1 + 10, TOP_TRIGGER_WIN_Y1 + 16}, {TOP_TRIGGER_WIN_X1 + 16, TOP_TRIGGER_WIN_Y1 + 8}, {TOP_TRIGGER_WIN_X1 + 22, TOP_TRIGGER_WIN_Y1 + 16}};
//下降沿
const static GUI_POINT triggerFallingArrow[3] = {{TOP_TRIGGER_WIN_X1 + 10, TOP_TRIGGER_WIN_Y1 + 9}, {TOP_TRIGGER_WIN_X1 + 22, TOP_TRIGGER_WIN_Y1 + 9}, {TOP_TRIGGER_WIN_X1 + 16, TOP_TRIGGER_WIN_Y1 + 17}};
/*********************************************************************
*
*       Dialog resource
*
* This table conatins the info required to create the dialog.
* It has been created by ucGUIbuilder.
*/

static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
    {FRAMEWIN_CreateIndirect, "Oscilloscope", 0, 756, 0, 96, 480, 0, 0},
    {BUTTON_CreateIndirect, "Previous", GUI_ID_BUTTON0, 4, 15, 84, 60, 0, 0},
    {BUTTON_CreateIndirect, "Run/Stop", GUI_ID_BUTTON1, 4, 111, 84, 60, 0, 0},
    {BUTTON_CreateIndirect, "Measure", GUI_ID_BUTTON2, 3, 207, 84, 60, 0, 0},
    {BUTTON_CreateIndirect, "Cursor", GUI_ID_BUTTON3, 4, 303, 84, 60, 0, 0},
    {BUTTON_CreateIndirect, "Next", GUI_ID_BUTTON4, 4, 399, 84, 60, 0, 0}};

/**
 * @brief : 写文字
 * @param {*}
 * @return {*}
 */
static void drawText(int x, int y, int textColor, int bgColor, const GUI_FONT *font, int textMode, const char *str)
{
    GUI_SetColor(textColor);
    GUI_SetBkColor(bgColor);
    GUI_SetTextMode(textMode);
    GUI_SetFont(font);
    GUI_DispStringAt(str, x, y);
}
/**
 * @brief : 绘制触发状态
 * @param {*}
 * @return {*}
 */
static void drawTriggerState(uint8_t state)
{
#define TRIGGER_STATE_TRIGGERED 3
//自动
#define TRIGGER_STATE_AUTO 4
//普通触发
#define TRIGGER_STATE_NORMAL 5
//单次触发
#define TRIGGER_STATE_SINGLE 6
    switch (state)
    {
    case TRIGGER_STATE_TRIGGERED:
        drawText(45, 3, 0x0fe04a, INFO_WIN_BG_COLOR, &GUI_Font24_ASCII, GUI_TEXTMODE_TRANS, "T'D");

        break;
    case TRIGGER_STATE_AUTO:
        drawText(45, 3, 0x0fe04a, INFO_WIN_BG_COLOR, &GUI_Font24_ASCII, GUI_TEXTMODE_TRANS, "AUTO");

        break;
    case TRIGGER_STATE_NORMAL:
        drawText(45, 3, 0x0fe04a, INFO_WIN_BG_COLOR, &GUI_Font24_ASCII, GUI_TEXTMODE_TRANS, "NORMAL");

        break;
    case TRIGGER_STATE_SINGLE:
        drawText(45, 3, 0x0fe04a, INFO_WIN_BG_COLOR, &GUI_Font24_ASCII, GUI_TEXTMODE_TRANS, "SINGLE");

        break;
    }
}
/**
 * @brief : 在左上角绘制光标测量的信息，以及一些与其他信息
 * @param {*}
 * @return {*}
 */
static void showCursorInfo(OscillInfo *paramList)
{
    int i, j, m = 0;
    uint8_t cnt = 0;
    char str[30];
    uint8_t needToshow[8] = {0};
    for (i = 0; i < 8; i++)
    {
        //记录一共要显示的数据的总数和序号
        if (paramList[i].isShowed == 1)
        {
            cnt++;
            needToshow[m++] = paramList[i].ID;
        }
    }

    for (j = 0; j < cnt; j++)
    {
        //printf("s:%s\n", paramList[needToshow[j]].unit);
        sprintf(str, "%s:%.2f %s",
                paramList[needToshow[j]].str,
                paramList[needToshow[j]].value,
                paramList[needToshow[j]].unit);
        drawText(42,
                 43 + j * 29,
                 paramList[needToshow[j]].color == GUI_WHITE ? LINE_COLOR : paramList[needToshow[j]].color,
                 INFO_WIN_BG_COLOR,
                 &GUI_Font24_ASCII,
                 GUI_TEXTMODE_NORMAL, str);
    }
}
/**
 * @brief : 根据结构体中的数据自动调整并显示数据在屏幕下方
 * @param {*}
 * @return {*}
 */
static void showParam(OscillInfo *paramList)
{
    int i, j, m = 0;
    uint8_t cnt = 0;
    char str[30];
    uint8_t needToshow[5] = {0};
    for (i = 0; i < 5; i++)
    {
        //记录一共要显示的数据的总数和序号
        if (paramList[i].isShowed == 1)
        {
            cnt++;
            needToshow[m++] = paramList[i].ID;
        }
    }

    for (j = 0; j < cnt; j++)
    {
        sprintf(str, "%s:%.2f %s",
                paramList[needToshow[j]].str,
                paramList[needToshow[j]].value,
                paramList[needToshow[j]].unit);
        drawText(52 + (j % 4) * 175,
                 409 - (j / 4) * 31,
                 paramList[j].color == GUI_WHITE ? LINE_COLOR : paramList[j].color,
                 METER_BG_COLOR,
                 &GUI_Font24_ASCII,
                 GUI_TEXTMODE_TRANS, str);
    }
}
/**
 * @brief : 绘制触发方式符号
 * @param {*}
 * @return {*}
 */
static void drawTiggerSign(uint8_t triggerType, float voltage)
{
    GUI_SetColor(LINE_COLOR);
    GUI_SetPenSize(2);
    GUI_DrawLine(TOP_TRIGGER_WIN_X1 + 16, TOP_TRIGGER_WIN_Y1 + 3, TOP_TRIGGER_WIN_X1 + 16, TOP_TRIGGER_WIN_Y1 + 3 + 21);

    if (triggerType == TRIG_TYPE_RISING)
    {
        GUI_DrawLine(TOP_TRIGGER_WIN_X1 + 5, TOP_TRIGGER_WIN_Y1 + 22, TOP_TRIGGER_WIN_X1 + 5 + 12, TOP_TRIGGER_WIN_Y1 + 22);
        GUI_DrawLine(TOP_TRIGGER_WIN_X1 + 16, TOP_TRIGGER_WIN_Y1 + 3, TOP_TRIGGER_WIN_X1 + 16 + 12, TOP_TRIGGER_WIN_Y1 + 3);
        GUI_FillPolygon(triggerRisingArrow, 3, 0, 0);
    }
    else
    {
        GUI_DrawLine(TOP_TRIGGER_WIN_X1 + 5, TOP_TRIGGER_WIN_Y1 + 3, TOP_TRIGGER_WIN_X1 + 5 + 12, TOP_TRIGGER_WIN_Y1 + 3);
        GUI_DrawLine(TOP_TRIGGER_WIN_X1 + 16, TOP_TRIGGER_WIN_Y1 + 22, TOP_TRIGGER_WIN_X1 + 16 + 12, TOP_TRIGGER_WIN_Y1 + 22);
        GUI_FillPolygon(triggerFallingArrow, 3, 0, 0);
    }
    sprintf(triggerVoltageString, "%.3f V", voltage);
    drawText(TOP_TRIGGER_WIN_X1 + 36, TOP_TRIGGER_WIN_Y1, LINE_COLOR, INFO_WIN_BG_COLOR, &GUI_Font24_ASCII, GUI_TEXTMODE_NORMAL, triggerVoltageString);
}

/**
 * @brief : 绘制当前波形在内存中的位置，是一个矩形，将当前窗口框选起来
 * @param {uint16_t}width :窗口时长和有效数据总时长之比
 * @param {int}midPos：矩形的偏移，为正往右偏移，为负往左偏移，单位像素
 * @return {*}
 */
static void drawWaveRect(float width, int midPos)
{
    int x0, y0, x1, y1;
    uint16_t w = (int)((float)TOP_WAVE_WIN_WIDTH * width);
    y0 = 8;
    y1 = 27;
    x0 = 391 - w / 2 + midPos;
    x1 = 391 + w / 2 + midPos;
    GUI_SetColor(0x2196f3);
    GUI_SetPenSize(2);
    GUI_DrawRect(x0, y0, x1, y1);
    GUI_DrawRect(x0 + 1, y0 + 1, x1 - 1, y1 - 1);
    GUI_DrawRect(x0 + 2, y0 + 2, x1 - 2, y1 - 2);
}
/**
 * @brief : 绘制顶端波形位置指示窗口
 * @param {*}
 * @return {*}
 */
static void drawWaveWin(void)
{
    GUI_SetColor(LINE_COLOR);
    GUI_SetPenSize(3);
    signed short point[616 - 168];
    int i = 0;
    for (i = 0; i < 616 - 168; i++)
    {
        point[i] = (signed short)(4 * sin(i * DEG2RAD * 10));
    }
    GUI_DrawGraph(point, 616 - 168, 168, 15);
}
/**
 * @brief : 绘制箭头
 * @param {*}
 * @return {*}
 */
static void drawArrow(void)
{
    int i = 0;
    GUI_POINT leftArrowtmp[5];
    GUI_POINT topArrowtmp[5];

    //if (abs(V_arrowoffset) > METER_WINDOW_HEIGHT / 2)
    {
        GUI_SetColor(LINE_COLOR);
        for (i = 0; i < 5; i++)
        {
            leftArrowtmp[i].x = leftArrow[i].x;
            leftArrowtmp[i].y = leftArrow[i].y - V_arrowoffset;
        }
    }
    // else
    // {
    //     GUI_SetColor(LINE_COLOR);
    //     for (i = 0; i < 5; i++)
    //     {
    //         leftArrowtmp[i].x = leftArrow[i].x;
    //         leftArrowtmp[i].y = leftArrow[i].y - V_arrowoffset > 0 ? METER_WINDOW_HEIGHT / 2 : (-METER_WINDOW_HEIGHT / 2);
    //     }
    // }

    GUI_FillPolygon(leftArrowtmp, 5, 0, 0);

    if (abs(V_arrowoffset) > METER_WINDOW_WIDTH / 2)
    {
        GUI_SetColor(GUI_WHITE);
        for (i = 0; i < 5; i++)
        {
            topArrowtmp[i].x = topArrow[i].x + V_arrowoffset > 0 ? METER_WINDOW_WIDTH / 2 : (-METER_WINDOW_WIDTH / 2);
            topArrowtmp[i].y = topArrow[i].y;
        }
    }
    else
    {
        GUI_SetColor(LINE_COLOR);
        for (i = 0; i < 5; i++)
        {
            topArrowtmp[i].x = topArrow[i].x + H_arrowoffset;
            topArrowtmp[i].y = topArrow[i].y;
        }
    }

    GUI_FillPolygon(topArrowtmp, 5, 0, 0);
}
/**
 * @brief : 绘制光标
 * @param {*}
 * @return {*}
 */
static void drawCursor(void)
{
    int which;

    for (which = 0; which < 5; which++)
    {
        //竖线光标
        if (Cursors[which].type == CURSOR_TYPE_Y && Cursors[which].isVisible == 1)
        {

            GUI_SetColor(Cursors[which].color);
            GUI_DrawLine(Cursors[which].pos + LEFT_PADDING, TOP_PADDING, Cursors[which].pos + LEFT_PADDING, METER_WINDOW_HEIGHT + TOP_PADDING);
            //GUI_SetColor(LINE_COLOR);
            //GUI_DrawCircle(Cursors[which].value + LEFT_PADDING, displayData[Cursors[which].value].y + TOP_PADDING, 5);
        }
        //横线光标
        else if (Cursors[which].type == CURSOR_TYPE_X && Cursors[which].isVisible == 1)
        {
            GUI_SetColor(Cursors[which].color);
            GUI_DrawLine(LEFT_PADDING, Cursors[which].pos + TOP_PADDING, LEFT_PADDING + METER_WINDOW_WIDTH, Cursors[which].pos + TOP_PADDING);
        }
        //触发位置光标
        else if (Cursors[which].type == CURSOR_TYPE_TRIGGER && Cursors[which].isVisible == 1)
        {
            GUI_SetColor(Cursors[which].color);
            GUI_DrawLine(LEFT_PADDING, Cursors[which].pos + TOP_PADDING, LEFT_PADDING + METER_WINDOW_WIDTH, Cursors[which].pos + TOP_PADDING);
        }
    }
}
/**
 * @brief : 绘制刻度
 * @param {*}
 * @return {*}
 */
static void drawScale(void)
{
    int i = 0;
    GUI_SetColor(0x7c879b);
    GUI_SetPenSize(1);
    for (i = 0; i < HORIZON_SCALE_CNT + 1; i++)
    {
        if (i == 3)
        {
            GUI_SetPenSize(2);
        }
        else
        {
            GUI_SetPenSize(1);
        }
        GUI_DrawVLine(LEFT_PADDING + i * (METER_WINDOW_WIDTH / HORIZON_SCALE_CNT), TOP_PADDING, TOP_PADDING + METER_WINDOW_HEIGHT);
    }
    GUI_SetPenSize(2);
    GUI_DrawHLine(Y_MIDDEL, LEFT_PADDING, LEFT_PADDING + METER_WINDOW_WIDTH);
    GUI_SetPenSize(1);
    GUI_DrawHLine(Y_MIDDEL + SCALE_LENGHT, LEFT_PADDING, LEFT_PADDING + METER_WINDOW_WIDTH);
    GUI_DrawHLine(Y_MIDDEL + SCALE_LENGHT * 2, LEFT_PADDING, LEFT_PADDING + METER_WINDOW_WIDTH);
    GUI_DrawHLine(Y_MIDDEL + SCALE_LENGHT * 3, LEFT_PADDING, LEFT_PADDING + METER_WINDOW_WIDTH);
    GUI_DrawHLine(Y_MIDDEL - SCALE_LENGHT, LEFT_PADDING, LEFT_PADDING + METER_WINDOW_WIDTH);
    GUI_DrawHLine(Y_MIDDEL - SCALE_LENGHT * 2, LEFT_PADDING, LEFT_PADDING + METER_WINDOW_WIDTH);
    GUI_DrawHLine(Y_MIDDEL - SCALE_LENGHT * 3, LEFT_PADDING, LEFT_PADDING + METER_WINDOW_WIDTH);
}
/**
 * @brief : 绘制各种底色
 * @param {*}
 * @return {*}
 */
static void drawInfo(void)
{
    GUI_SetColor(GUI_WHITE);
    GUI_SetBkColor(BG_COLOR);
    //绘制外壳背景
    GUI_ClearRect(0, 0, LCD_HEIGHT, TOP_PADDING);
    GUI_ClearRect(0, TOP_PADDING, LEFT_PADDING, LCD_WIDTH);
    GUI_ClearRect(LEFT_PADDING, TOP_PADDING + METER_WINDOW_HEIGHT, LCD_HEIGHT, LCD_WIDTH);
    GUI_ClearRect(LEFT_PADDING + METER_WINDOW_WIDTH, TOP_PADDING, LCD_HEIGHT, LCD_WIDTH - BOTTOM_PADDING);

    GUI_SetBkColor(INFO_WIN_BG_COLOR);

    //示波器窗口背景
    GUI_ClearRect(TOP_WAVE_WIN_X1,
                  TOP_WAVE_WIN_Y1,
                  TOP_WAVE_WIN_X2,
                  TOP_WAVE_WIN_Y2);
    //运行状态指示框背景
    GUI_ClearRect(TOP_RUNNING_STATE_WIN_X1,
                  TOP_RUNNING_STATE_WIN_Y1,
                  TOP_RUNNING_STATE_WIN_X2,
                  TOP_RUNNING_STATE_WIN_Y2);
    //触发状态指示框背景
    GUI_ClearRect(TOP_TRIGGER_WIN_X1,
                  TOP_TRIGGER_WIN_Y1,
                  TOP_TRIGGER_WIN_X2,
                  TOP_TRIGGER_WIN_Y2);

    drawWaveWin();
}
/**
 * @brief : 绘制示波器背景
 * @param {WM_MESSAGE} *pMsg
 * @return {*}
 */
static void drawMeterbg(void)
{
    GUI_SetBkColor(METER_BG_COLOR);
    //绘制窗口背景
    GUI_ClearRect(LEFT_PADDING, TOP_PADDING, 756, 450);
    //绘制刻度线
    drawScale();
}
/**
 * @brief : 绘制波形和背景
 * @param {void* }p 需要绘制的波形数据
 * @return {*}
 */
static void drawLoop(void *p)
{
    int i = 0;
    //绘制不变的背景
    if (AutoDevInfo.DrawFixed || useGram == 0)
    {

        drawMeterbg();
    }
    //绘制波形点
    if (p != NULL)
    {
        GUI_SetColor(LINE_COLOR);
        GUI_SetPenSize(1);
        //最多只绘制窗口宽度这么多数据

        GUI_DrawPolyLine((GUI_POINT *)p, PointSize > METER_WINDOW_WIDTH ? METER_WINDOW_WIDTH : PointSize, LEFT_PADDING, TOP_PADDING);
    }
    if (AutoDevInfo.DrawFixed || useGram == 0)
    {

        drawInfo();
    }
    drawWaveRect(WaveRectWidth, WaveRectMidPos);
    //绘制触发标志和触发电压
    drawTiggerSign(triggerType, triggerVoltage);
    //绘制光标
    drawCursor();
    //绘制箭头
    drawArrow();
    //绘制刻度值
    drawText(55, 452, LINE_COLOR, 0x424242, &GUI_Font24_ASCII, GUI_TEXTMODE_NORMAL, V_Scale);
    drawText(520, 452, GUI_WHITE, 0x424242, &GUI_Font24_ASCII, GUI_TEXTMODE_NORMAL, H_Scale);
    drawTriggerState(triggerState);
    //显示参数
    showParam(ParamList);
    //绘制左上角信息
    showCursorInfo(CursorParamList);
}

/*****************************************************************
**      FunctionName:void PaintDialog(WM_MESSAGE * pMsg)
**      Function: to initialize the Dialog items
**                                                      
**      call this function in _cbCallback --> WM_PAINT
*****************************************************************/

static void PaintDialog(WM_MESSAGE *pMsg)
{
    WM_HWIN hWin = pMsg->hWin;

    //BUTTON_SetText(WM_GetDialogItem(hWin, GUI_ID_BUTTON0), "Previous");
    BUTTON_SetText(WM_GetDialogItem(hWin, GUI_ID_BUTTON1), menuInfo[CurrentMenuPageNum * 3 + 0].str);
    BUTTON_SetText(WM_GetDialogItem(hWin, GUI_ID_BUTTON2), menuInfo[CurrentMenuPageNum * 3 + 1].str);
    BUTTON_SetText(WM_GetDialogItem(hWin, GUI_ID_BUTTON3), menuInfo[CurrentMenuPageNum * 3 + 2].str);
    //BUTTON_SetText(WM_GetDialogItem(hWin, GUI_ID_BUTTON4), "Next");
}

/**
 * @brief : 初始化侧边窗口
 * @param {*}
 * @return {*}
 */
static void InitDialog(WM_MESSAGE *pMsg)
{

    WM_HWIN hWin = pMsg->hWin;
    //
    //FRAMEWIN
    //
    FRAMEWIN_SetBarColor(hWin, 1, 0x908070);
    FRAMEWIN_SetClientColor(hWin, 0x646464);
    FRAMEWIN_SetTextAlign(hWin, GUI_TA_VCENTER | GUI_TA_CENTER);
    FRAMEWIN_SetTitleVis(hWin, 0);
    FRAMEWIN_SetTitleHeight(hWin, 20);
    //
    //GUI_ID_BUTTON0
    //
    BUTTON_SetFont(WM_GetDialogItem(hWin, GUI_ID_BUTTON0), &GUI_Font24_ASCII);
    //
    //GUI_ID_BUTTON1
    //
    BUTTON_SetFont(WM_GetDialogItem(hWin, GUI_ID_BUTTON1), &GUI_Font24_ASCII);
    //
    //GUI_ID_BUTTON2
    //
    BUTTON_SetFont(WM_GetDialogItem(hWin, GUI_ID_BUTTON2), &GUI_Font24_ASCII);
    //
    //GUI_ID_BUTTON3
    //
    BUTTON_SetFont(WM_GetDialogItem(hWin, GUI_ID_BUTTON3), &GUI_Font24_ASCII);
    //
    //GUI_ID_BUTTON4
    //
    BUTTON_SetFont(WM_GetDialogItem(hWin, GUI_ID_BUTTON4), &GUI_Font24_ASCII);

    BUTTON_SetText(WM_GetDialogItem(hWin, GUI_ID_BUTTON0), "Previous");
    //BUTTON_SetText(WM_GetDialogItem(hWin, GUI_ID_BUTTON1), menuInfo[0].str);
    //BUTTON_SetText(WM_GetDialogItem(hWin, GUI_ID_BUTTON2), menuInfo[1].str);
    //BUTTON_SetText(WM_GetDialogItem(hWin, GUI_ID_BUTTON3), menuInfo[2].str);
    BUTTON_SetText(WM_GetDialogItem(hWin, GUI_ID_BUTTON4), "Next");
}
/**
 * @brief :
 * @param {*}
 * @return {*}
 */
WM_HWIN getMainWin(void)
{
    if (Hwin != NULL)
    {
        return Hwin;
    }
}
/**
 * @brief : 侧边按键窗口回调
 * @param {*}
 * @return {*}
 */
static void _cbCallback(WM_MESSAGE *pMsg)
{
    int NCode, Id;
    WM_HWIN hWin = pMsg->hWin;
    switch (pMsg->MsgId)
    {
    case WM_PAINT:
        PaintDialog(pMsg);
        break;
    case WM_INIT_DIALOG:
        InitDialog(pMsg);
        break;
    case WM_KEY:
        switch (((WM_KEY_INFO *)(pMsg->Data.p))->Key)
        {
        case GUI_KEY_ESCAPE:
            GUI_EndDialog(hWin, 1);
            break;
        case GUI_KEY_ENTER:
            GUI_EndDialog(hWin, 0);
            break;
        }
        break;
    case WM_NOTIFY_PARENT:
        Id = WM_GetId(pMsg->hWinSrc);
        NCode = pMsg->Data.v;
        switch (Id)
        {
        case GUI_ID_OK:
            if (NCode == WM_NOTIFICATION_RELEASED)
                GUI_EndDialog(hWin, 0);
            break;
        case GUI_ID_CANCEL:
            if (NCode == WM_NOTIFICATION_RELEASED)
                GUI_EndDialog(hWin, 0);
            break;
        case GUI_ID_BUTTON0:
            switch (NCode)
            {
            case WM_NOTIFICATION_CLICKED:
                OnButton1Clicked(pMsg);
                break;
            }
            break;
        case GUI_ID_BUTTON1:
            switch (NCode)
            {
            case WM_NOTIFICATION_CLICKED:
                OnButton2Clicked(pMsg);
                break;
            }
            break;
        case GUI_ID_BUTTON2:
            switch (NCode)
            {
            case WM_NOTIFICATION_CLICKED:
                OnButton3Clicked(pMsg);
                break;
            }
            break;
        case GUI_ID_BUTTON3:
            switch (NCode)
            {
            case WM_NOTIFICATION_CLICKED:
                OnButton4Clicked(pMsg);
                break;
            }
            break;
        case GUI_ID_BUTTON4:
            switch (NCode)
            {
            case WM_NOTIFICATION_CLICKED:
                OnButton5Clicked(pMsg);
                break;
            }
            break;
        }
        break;
    default:
        WM_DefaultProc(pMsg);
    }
}
/**
 * @brief : 背景窗口回调
 * @param {*}
 * @return {*}
 */
static void cbBgWin(WM_MESSAGE *pMsg)
{
    switch (pMsg->MsgId)
    {
    case WM_PAINT:
        /* code */
        drawMeterbg();
        //printf("cbBgWin WM_PAINT\n");
        break;

    default:
        WM_DefaultProc(pMsg);
        // printf("WM_DefaultProc\n");
        break;
    }
}
static void _ShowText(const char *sText)
{
    GUI_SetColor(GUI_BLACK);
    GUI_SetBkColor(GUI_WHITE);

    GUI_ClearRect(0, 0, 854, 450);
    GUI_SetFont(&GUI_FontComic18B_ASCII);
    GUI_DispStringAt(sText, 10, 20);
}
/**
 * @brief : 侧边按键按下后监听函数
 * @param {WM_MESSAGE} *pMsg
 * @param {uint8_t} itemNum
 * @return {*}
 */
// {"Auto", "Run/Stop", "Measure", "Trigger", "Cursor", "test2", "test3", "test4", "test5"};
void onViewMenuItemClicked(WM_MESSAGE *pMsg, uint8_t itemNum)
{
    int i;
    switch (itemNum)
    {
    case 0:
        /* code */
        if (CurrentMenuPageNum > 0)
        {
            int i;
            CurrentMenuPageNum--;

            for (i = 0; i < 3; i++)
            {
                strcpy(menuStr[i + 1], (menuInfo[CurrentMenuPageNum * 3 + i].str));
            }
            BUTTON_SetBkColor(WM_GetDialogItem(pMsg->hWin, GUI_ID_BUTTON1), 0, menuInfo[0].unClickedColor);

            WM_InvalidateWindow(WM_GetClientWindow(pMsg->hWin));
        }
        else
        {
            GUI_EndDialog(Hwin, 0);
            V_goHome();
        }
        break;
    case 1:
        /* code */
        switch (CurrentMenuPageNum)
        {
        case 0:
            /* code */
            M_Auto();

            break;
        case 1:
            /* code */
            M_changeTirggerType();
            break;
        case 2:
            /* code */
            break;
        case 3:
            /* code */
            break;
        default:
            break;
        }
        break;
    case 2:
        /* code */
        switch (CurrentMenuPageNum)
        {
        case 0:
            /* code */
            M_Run_Stop();

            break;
        case 1:
            /* code */
            createCursorWin();
            break;
        case 2:
            /* code */
            break;
        case 3:
            /* code */
            break;
        default:
            break;
        }
        break;
    case 3:
        /* code */
        switch (CurrentMenuPageNum)
        {
        case 0:
            /* code */
            createMeasureWin(0);

            break;
        case 1:
            /* code */
            break;
        case 2:
            /* code */
            break;
        case 3:
            /* code */
            break;
        default:
            break;
        }
        break;
    case 4:
        /* code */
        //不是最后一页

        if (CurrentMenuPageNum < MenuCnt / 3)
        {
            CurrentMenuPageNum++;
            for (i = 0; i < 3; i++)
            {
                strcpy(menuStr[i + 1], (menuInfo[CurrentMenuPageNum * 3 + i].str));
            }
            WM_InvalidateWindow(WM_GetClientWindow(pMsg->hWin));
        }

        break;
    default:
        break;
    }
    WM_InvalidateWindow(WM_GetClientWindow(pMsg->hWin));
}
/*******************view层执行函数*************************/

void onViewOscillUI_Init(void)
{

#ifdef USE_GRAM
    useGram = 1;
#else
    useGram = 0;
#endif // DEBUG

    WM_SetCallback(WM_HBKWIN, cbBgWin);
    GUI_MEMDEV_CreateAuto(&AutoDev);
    setCursor(Cursors);
    setLeftSideInfo(CursorParamList);
    Hwin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);
}
void onViewSetH_Scale(const char *str)
{
    strcpy(H_Scale, str);
}
void onViewsetV_Scale(const char *str)
{
    strcpy(V_Scale, str);
}
/**
 * @brief : 设置波形数据
 * @param {GUI_POINT} *data 波形数据
 * @param {unsignedint} size 需要显示的点数,点数如果大于示波器窗口分辨率的部分将不会显示，且该函数不做检查
 * @return {*}
 */
void onViewSetGraph(GUI_POINT *data, unsigned int size)
{
    displayData = data;
    PointSize = size;
}
/**
 * @brief : 单独更改显示点数，不常用
 * @param {int} size
 * @return {*}
 */
void onViewSetGraphSize(int size)
{
    PointSize = size;
}
/**
 * @brief : 执行一次波形绘制，波形数据设置使用onViewSetGraph完成
 * @param {WM_MESSAGE} *pMsg
 * @return {*}
 * @说明：此函数绘制的图形是使用负坐标显示的，原点在示波器窗口左上角，
 * 所以要显示的数据必须提前先处理好显示的位置等，该函数不负责处理数据
 */
 void onViewdrawGraph(WM_MESSAGE *pMsg)
{
    //drawLoop(displayData);
    if (useGram == 1)
    {
        GUI_MEMDEV_DrawAuto(&AutoDev, &AutoDevInfo, drawLoop, displayData);
    }
    else
    {
        drawLoop(displayData);
    }
    //drawMeterbg();
}

/**
 * @brief : 设置运行状态
 * @param {unsignedchar} state 
 * @return {*}
 */
void onViewSetHoldState(unsigned char state)
{
    if (state == 1)
    {
        BUTTON_SetBkColor(WM_GetDialogItem(Hwin, GUI_ID_BUTTON1), 0, 0xB6B6AA);
    }
    else
    {
        BUTTON_SetBkColor(WM_GetDialogItem(Hwin, GUI_ID_BUTTON1), 0, 0xDC143C);
    }
}

/**
 * @brief : 设置水平箭头偏移，使用正坐标系
 * @param {uint16_t} offset 正为向左偏移
 * @return {*}
 */
void onViewSetH_Offset(int offset)
{
    H_arrowoffset = offset;
}
/**
 * @brief : 设置垂直箭头偏移，使用正坐标系
 * @param {uint16_t} offset 正为向上偏移
 * @return {*}
 */
void onViewSetV_Offset(int offset)
{
    V_arrowoffset = offset;
}
/**
 * @brief : 设置触发方式
 * @param {uint8_t} type 和adc trigtype一样
 * @return {*}
 */
void onViewSetTriggerType(uint8_t type)
{
    triggerType = type;
}
/**
 * @brief : 设置触发电压
 * @param {float} voltage 电压
 * @return {*}
 */
void onViewSetTriggerVoltage(float voltage)
{
    triggerVoltage = voltage;
}
/**
 * @brief : 设置测量数据的结构体
 * @param {OscillInfo} *list
 * @return {*}
 */
void onViewSetOscillDataList(OscillInfo *list)
{
    ParamList = list;
    onViewSetMeasureDataList(list);
}

/**
 * @brief : 设置触发状态
 * @param {uint8_t} state
 * @return {*}
 */
void onViewSetTriggerState(uint8_t state)
{
    triggerState = state;
}

/**
 * @brief : 设置菜单
 * @param {MenuInfo} *m
 * @param {uint8_t} itemCnt
 * @return {*}
 */
void onViewSetMenuInfo(MenuInfo *m, uint8_t itemCnt)
{
    menuInfo = m;
    MenuCnt = itemCnt;
}
void onViewSetCursor(Cursor *c)
{
    Cursors = c;
}
void onViewSetWaveWinInfo(float width, int pos)
{
    WaveRectWidth = width;
    WaveRectMidPos = pos;
}
void onViewSetCursorListInfo(OscillInfo *p)
{
    CursorParamList = p;
    setLeftSideInfo(CursorParamList);
}
#endif